'''
Created on 2012-10-11

@author: Alexandre
'''
class Grille:
    
    coordCanon = ((4, 0), (5, 0), (4, 1), (5, 1), (4, 10), (5, 10), \
                  (6, 10), (3, 11), (7, 11), (2, 12), (8, 12), (2, 13), \
                  (8, 13), (5, 14), (3, 15), (7, 15), (4, 16), (5, 16), \
                  (6, 16), (5, 17), (2, 20), (3, 20), (4, 20), (2, 21), \
                  (3, 21), (4, 21), (1, 22), (5, 22), (0, 24), (1, 24), \
                  (5, 24), (6, 24), (2, 34), (3, 34), (2, 35), (3, 35))
    
    def __init__(self):
        self.dimensionX = 0
        self.dimensionY = 0
        self.grilleCase = list()
        self.changement = list()
    def __str__(self):
        s = ""
        for i in range(self.dimensionX):
            for j in range(self.dimensionY):
                if self.grilleCase[i][j].valeur:
                    s += "*"
                else:
                    s += '-'
            s += '\n'
        return s
    def setDimensions(self, x, y):
        self.dimensionX = int(x)
        self.dimensionY = int(y)
        self.regenererGrille()
        
    def regenererGrille(self):
        grilleTemp = []
        for x in range(self.dimensionX):
            listeTemp = []
            for y in range(self.dimensionY):
                try:
                    listeTemp.append(self.grilleCase[x][y])
                except IndexError:
                    listeTemp.append(Case())
            grilleTemp.append(listeTemp)
        self.grilleCase = grilleTemp
    def effacer(self):
        for x in range(self.dimensionX):
            for y in range(self.dimensionY):
                self.grilleCase[x][y].valeur = False
    def genererCanon(self):
        if self.dimensionX >= 9 and self.dimensionY >= 36:
            self.effacer()
            for coord in Grille.coordCanon:
                x = coord[0]; y = coord[1]
                self.grilleCase[x][y].valeur = True
            
    def setCase(self, x, y, valeur=True):
        self.grilleCase[x][y].valeur = valeur
    def inverserCase(self, x, y):
        self.grilleCase[x][y].valeur = not self.grilleCase[x][y].valeur
    def prochaineGrille(self):
        self.changement = []
        for i in range(self.dimensionX):
            for j in range(self.dimensionY):
                self.calculerVoisinsCases(i, j)
                if self.grilleCase[i][j].calculProchaineValeur():
                    self.changement.append((i, j))
        for x in range(self.dimensionX):
            for y in range(self.dimensionY):                
                self.grilleCase[x][y].valeur = self.grilleCase[x][y].prochaineValeur
    def calculerVoisinsCases(self, x, y):
        compte = 0
        for i in (-1, 0, 1):
            for j in (-1, 0, 1):
                if not(i==0 and j==0) and x+i >= 0 and y+j >= 0\
                and x+i < self.dimensionX and y+j < self.dimensionY:
                    if self.grilleCase[x+i][y+j].valeur:
                        compte += 1
        self.grilleCase[x][y].voisins = compte
        #print('(',x,y,")",":",compte)
        
    
class Case:
    def __init__(self, valeur=False):
        self.valeur = valeur
        self.voisins = 0
        self.prochaineValeur = False
    def calculProchaineValeur(self):
        change = False
        if self.valeur and not(self.voisins == 2 or self.voisins == 3):
            self.prochaineValeur = False
            change = True
        elif self.valeur and (self.voisins == 2 or self.voisins == 3):
            self.prochaineValeur = True
        elif not self.valeur and self.voisins == 3:
            self.prochaineValeur = True
            change = True
        else:
            self.prochaineValeur = False
        return change

if __name__ == "__main__":
    '''g = Grille()
    g.setDimensions(5, 5)
    
    g.setCase(1, 2)
    #g.setCase(2, 1)
    #g.setCase(2, 2)
    #g.setCase(2, 3)
    g.setCase(3, 2)
    g.setCase(4, 2)
    g.setCase(3, 1)
    
    for a in range(10):
        print(g.changement)
        g.prochaineGrille()
        print(str(g))
        
    g.setDimensions(7, 7)
    print(str(g))'''
    g = Grille()
    g.setDimensions(40, 40)
    g.genererCanon()
    print(g)

    